<?php

if ( !defined( "RUTA_FISICA_SISTEMA" ) )
{
   require_once '../../../../config/Constantes.php';
}

$ruta_sistema = RUTA_FISICA_SISTEMA . "/sistema/";

require_once $ruta_sistema . "general/clases/comun/archivos/OperacionArchivo.php";
require_once $ruta_sistema . "general/clases/comun/General.php";
require_once $ruta_sistema . "general/clases/comun/logger/LogBD.php";

/**
 * 
 * Autor				: 	Juan Jose Muñiz Juarez
 * Fecha de Creacion	: 	21/04/2012,  01:45:59
 * Version 				: 	1.0
 * Descripcion 			:   Permite la generacion de informacion de logs y la permite exportar a varias salidas
 *                          segun se especifique en la configuracion del sistema y estas pueden ser las siguientes:
 *                                <ul>
 *                                   <li>Log : Envia la salida a un archivo log</li>
 *                                   <li>Base de Datos: Envia la informacion del log una tabla en la base de datos</li>
 *                                </ul>
 */
class Logger
   {
      public static $DEBUG = 1;
      public static $INFO  = 2;
      public static $WARN  = 3;
      public static $ERROR = 4;
      public static $FATAL = 5;
      
      private $_class;
      private $_formato_fecha;
      private $_contenido;
      private $_registrar_fecha;
      private $_acumular_log;
      private $_logs;
      
         /**
          * 
          * Metodo: __construct
          * Descripcion: 
          * Fecha de Creacion: 18/04/2012 13:05:43
          * Autor: Juan José Muñiz Juárez
          * params: @param unknown_type $class
          * params: @param unknown_type $acumular_log
          * params: @param unknown_type $registrar_fecha
          * params: @param unknown_type $formato_fecha
          * return: return_type
          */
      public function __construct( $class, $acumular_log = false, $registrar_fecha = true , $formato_fecha = "d/m/Y h:i:s a" )
        {
           $this -> setClass( $class );
           $this -> setFormato_fecha( $formato_fecha );
           $this -> setRegistrar_fecha( $registrar_fecha );
           
           $this -> _acumular_log = $acumular_log;
           
           if ( $acumular_log )
             {
                $this -> _logs = array();
             }
        } 
        
      public function getClass()
        {
           return $this -> _class;
        }  
        
      public function setClass( $class)
        {
           $this -> _class = $class;
        }

	/**
     * @param field_type $_formato_fecha
     */
      public function setFormato_fecha( $_formato_fecha )
         {
            $this->_formato_fecha = $_formato_fecha;
         }
   
	/**
     * @param field_type $_registrar_fecha
     */
      public function setRegistrar_fecha( $_registrar_fecha )
         {
            $this->_registrar_fecha = $_registrar_fecha;
         }
   
	/**
	 * 
	 * Nombre         	: 	log
	 * Descripcion   	:	Metodo generico que envia la informacion a la traza que se establezca en el parametro $level, por default es DEBUG
	 * Version 			:  	1.0
	 * Autor:			:	Juan Jose Muñiz Juarez
	 * Fecha y Hora		:	26/04/2012, 22:10:05
	 * @param unknown_type $message   :   Mensaje que se va a enviar a la traza
	 * @param unknown_type $level   :   Nivel al cual se va a enviar el mensaje, por default es DEBUG
	 * @param unknown_type $method   :   Metodo que invoca la generacion del log, si no se especifica envia el del metodo log
	 * @param unknown_type $line   :   Linea que invoca la generacion del log, si no se especifica se envia el del metodo log
	 */
      public function log( $message, $level = 1, $method = null, $line = null )
        {
           if ( $message )
             {
                if ( $level )
                  {
                     if ( is_int( $level ) )
                       {
                          switch ( $level )
                            {
                               case LOGGER_DEBUG:
                                  {
                                     $this -> debug( $message, $method, $line  );
                                     break;
                                  }
                                  
                               case LOGGER_INFO:
                                  {
                                     $this -> info( $message, $method, $line  );                                                                         
                                     break;
                                  }

                               case LOGGER_WARN:
                                  {
                                     $this -> warn( $message, $method, $line  );
                                     break;
                                  }

                               case LOGGER_ERROR:
                                  {
                                     $this -> error( $message, $method, $line  );
                                     break;
                                  }
                               case LOGGER_FATAL:
                                  {
                                     $this -> fatal( $message, $method, $line  );
                                     break;
                                  }   
                               default:
                                  {
                                     //$this -> debug( $message, $method, $line  );
                                     //break;
                                     return null;
                                  }   
                            }
                       }
                  }
             }
          //echo $message . "-". $level; 
        }
        
        /**
         * 
         * Nombre         	: 	debug
         * Descripcion   	:	Envia la informacion por la traza DEBUG y escribe el contenido, ademas depende del nivel que 
         *                      se haya configurado en el sistema                      
         * Version 			:  	1.0
         * Autor:			:	Juan Jose Muñiz Juarez
         * Fecha y Hora		:	18/04/2012 12:38:08
         * @param unknown_type $message
         * @param unknown_type $method
         * @param unknown_type $line
         */
      public function debug( $message, $method = null, $line = null )
        {
           if ( LOGGER_DEBUG >= General::getNivelLog() )
             {
                $this -> construirCadenaContenido( LOGGER_DEBUG , $message, $method, $line );
             }
        }
        
        /**
         * 
         * Nombre         	: 	warn
         * Descripcion   	:	Envia el mensaje a la traza de WARN, depende de la configuracion que se haya hecho en 
         *                      el sistema, si el nivel es menor o igual a WARN se va a enviar la traza, en caso contrario no se enviara
         * Version 			:  	1.0
         * Autor:			:	Juan Jose Muñiz Juarez
         * Fecha y Hora		:	18/04/2012 12:38:12
         * @param unknown_type $message
         * @param unknown_type $method
         * @param unknown_type $line
         */
      public function warn( $message, $method = null, $line = null )
        {
           if ( LOGGER_WARN >= General::getNivelLog() )
             {
                $this -> construirCadenaContenido( LOGGER_WARN , $message, $method, $line );
             }
        }  
        
        /**
         * 
         * Nombre         	: 	fatal
         * Descripcion   	:	Envia el mensaje a la traza de FATAL, depende de la configuracion que se haya hecho en 
         *                      el sistema, si el nivel es menor o igual a FATAL se va a enviar la traza, en caso contrario no se enviara
         * Version 			:  	1.0
         * Autor:			:	Juan Jose Muñiz Juarez
         * Fecha y Hora		:	8/04/2012 12:38:40
         * @param unknown_type $message
         * @param unknown_type $method
         * @param unknown_type $line
         */
      public function fatal( $message, $method = null, $line = null )
        {
           if ( LOGGER_FATAL >= General::getNivelLog() )
             {
                $this -> construirCadenaContenido( LOGGER_FATAL, $message, $method, $line );
             }
        }  
        
        /**
         * 
         * Nombre         	: 	error
         * Descripcion   	:	Envia el mensaje a la traza de ERROR, depende de la configuracion que se haya hecho en 
         *                      el sistema, si el nivel es menor o igual a ERROR se va a enviar la traza, en caso contrario no se enviara
         * Version 			:  	1.0
         * Autor:			:	Juan Jose Muñiz Juarez
         * Fecha y Hora		:	18/04/2012 12:39:07
         * @param unknown_type $message
         * @param unknown_type $method
         * @param unknown_type $line
         */
      public function error( $message, $method = null, $line = null )
        {
           if ( LOGGER_ERROR  >= General::getNivelLog() )
             {
                $this -> construirCadenaContenido( LOGGER_ERROR, $message, $method, $line );
             }
        }  
        
        /**
         * 
         * Nombre         	: 	info
         * Descripcion   	:	Envia el mensaje a la traza de INFO, depende de la configuracion que se haya hecho en 
         *                      el sistema, si el nivel es menor o igual a INFO se va a enviar la traza, en caso contrario no se enviara
         * Version 			:  	1.0
         * Autor:			:	Juan Jose Muñiz Juarez
         * Fecha y Hora		:	26/04/2012, 22:09:23
         * @param unknown_type $message
         * @param unknown_type $method
         * @param unknown_type $line
         */
      public function info( $message,  $method = null, $line = null )
        {
           if ( LOGGER_INFO >= General::getNivelLog() )
             {
                $this -> construirCadenaContenido( LOGGER_INFO, $message, $method, $line );
             }
        }  
        
        /**
         * 
         * Nombre         	: 	construirCadenaContenido
         * Descripcion   	:	Permite generar el mensaje que se va a enviar a la opcion activada en el sistema 
         *                      y que se obtiene de General::getOpcionLog en la cual se especifica la salida del 
         *                      log , siguiendo una estructura determinada
         * Version 			:  	1.0
         * Autor:			:	Juan Jose Muñiz Juarez
         * Fecha y Hora		:	26/04/2012, 22:09:29
         * @param unknown_type $level
         * @param unknown_type $message
         * @param unknown_type $method
         * @param unknown_type $line
         * @return NULL
         */
      private function construirCadenaContenido( $level, $message, $method = null, $line = null )
        {
          //echo $message;
           if ( !$level )
             {
                return null;
             }
             
           $this -> _contenido = "NIVEL{";
             
           switch ( $level )
             {
                case LOGGER_DEBUG: //Logger::$DEBUG:
                   {
                      $this -> _contenido .= "DEBUG";
                      break;
                   }
                case LOGGER_INFO://Logger::$INFO:
                   {
                      $this -> _contenido .= "INFO";
                      break;
                   }
                case LOGGER_WARN://Logger::$WARN:
                   {
                      $this -> _contenido .= "WARN ";
                      break;
                   }

                case LOGGER_ERROR://Logger::$ERROR:
                   {
                      $this -> _contenido .= "ERROR";
                      break;
                   }
                   
                case LOGGER_FATAL://Logger::$FATAL:
                   {
                      $this -> _contenido .= "FATAL";
                      break;
                   }
                default:
                   {
                     return null;
                   }  
             } 
               
           $this -> _contenido .= "}";
           $this -> _contenido .= General::getSeparadorLog();
             
           if ( $this -> _class )
             {
                $this -> _contenido .= " CLASE{" . $this -> _class . "}" ;
             }  
           else
             {
                $this -> _contenido .= " ";
             }

           $this -> _contenido .= General::getSeparadorLog();
             
           if ( $method )
             {
                $this -> _contenido .= " METODO{" . $method . "}";
             }  
           else
             {
                $this -> _contenido .= " ";
             }

           $this -> _contenido .= General::getSeparadorLog();
             
           if ( $line )
             {
                $this -> _contenido .= " LINEA{" . $line. "}";
             }  
           else
             {
                $this -> _contenido .= " ";
             }

           $this -> _contenido .= General::getSeparadorLog(); 
             
           if ( $this -> _registrar_fecha )
             {
                $formato = $this -> _formato_fecha ? $this -> _formato_fecha : "d/m/Y h:i:s a";
             }
                          
           $this -> _contenido .= " FECHA{" . date( $formato ). "}";
           $this -> _contenido .= General::getSeparadorLog(); 
           $this -> _contenido .= " MENSAJE{" .str_replace( PHP_EOL , " ",  $message ). "}";
           $this -> _contenido .= General::getSeparadorLog();
           $this -> _contenido .= " SESION{" . General::getInformacionSesion(). "}";
           
           //echo "[" . $this -> _acumular_log . "]";
           
           if ( $this -> _acumular_log )
             {
                if ( !$this -> _logs )
                  {
                     $this -> _logs = array(); 
                  }
                  
                  $this -> _logs[] = $this -> _contenido;
             }
           else  
             {
                $opcion_log = General::getOpcionLog();
                
                if ( $opcion_log )
                  {
                     switch ( strtolower( $opcion_log ) )
                       {
                          case LOGGER_FILE:
                             {
                                $this -> escribirLog();
                                break;
                             }
                          case LOGGER_BASEDATOS:
                             {
                                $this -> escribirLogBD();
                                break;
                             }   
                       }
                  }
               
             }
        }  

        /**
         * 
         * Nombre         	: 	guardarAcumulacionLogs
         * Descripcion   	:	Guarda el contenido de los logs, que se envien a la clase, esto aplica cuando la bandera
         *                      <b>acumular_log</b>
         * Version 			:  	1.0
         * Autor:			:	Juan Jose Muñiz Juarez
         * Fecha y Hora		:	18/04/2012 12:00:59
         * @return boolean
         */
      public function guardarAcumulacionLogs()
        {
           if ( $this -> _acumular_log )
             {
                if ( $this -> _logs )
                  {
                     $archivo = fopen( General::nombreArchivoLogs(), FILE_TIPO_ACCESO_LECTURA_ESCRITURA_FINAL );
                     
                     if ( is_array( $this -> _logs ) && count( $this -> _logs ) )
                       {
                          foreach( $this -> _logs as $log )
                            {
                               try
                                 {
                                    //file_put_contents( General::nombreArchivoLogs() , $log . PHP_EOL, FILE_APPEND );
                                    fwrite( $archivo, $log . PHP_EOL );
                                 }
                               catch ( Exception $ex )
                                 {
                                    
                                 }  
                            }
                       }
                     else
                       {
                          //file_put_contents( General::nombreArchivoLogs() , $this -> _contenido . PHP_EOL, FILE_APPEND );
                          fwrite( $archivo, $this -> _contenido . PHP_EOL );
                       } 

                     fclose( $archivo );  
                  }
             }
             
            return false; 
        }  
        
        /**
         * 
         * Metodo: escribirLog
         * Descripcion: Escribe 
         * Fecha de Creacion: 18/04/2012 12:01:04
         * Autor: Juan José Muñiz Juárez
         * params: 
         * return: return_type
         */
       private function escribirLog() 
         {
           // echo "[" . $this -> _contenido . "]";
            // Aqui guardamos el contenido del log
            if ( $this -> _contenido )
             {
                file_put_contents( General::nombreArchivoLogs(), $this -> _contenido . PHP_EOL, FILE_APPEND );
             }
         }
         
         /**
          * 
          * Nombre         	: 	escribirLogBD
          * Descripcion   	:   Escribe lo datos de log en la base de datos 	
          * Version 		:  	1.0
          * Autor:			:	Juan Jose Mu�iz Juarez
          * Fecha y Hora	:	19/04/2012, 21:28:27
          */
       private function escribirLogBD()
         {
            //echo "Escribiendo log BD " .  $this -> _con;
            if ( $this -> _contenido )
              {
                 $contenido = explode ( General::getSeparadorLog(), $this -> _contenido );
                 $valores = array( "nivel" => $contenido[ 0 ],
                                   "clase" => $contenido[ 1 ],
                                   "metodo" => $contenido[ 2 ],
                                   "linea" => $contenido[ 3 ],
                                   "fecha" => $contenido[ 4 ],
                                   "log" => $contenido[ 5 ],
                                   "info_usuario" => $contenido[ 6 ] );
                 
                 $log_bd = new LogBD();
                 $log_bd -> setNivel( utf8_decode( $contenido[ 0 ] ) );
                 $log_bd -> setClase( utf8_decode( $contenido[ 1 ] ) );
                 $log_bd -> setMetodo( utf8_decode( $contenido[ 2 ] ) );
                 $log_bd -> setLinea( utf8_decode( $contenido[ 3 ] ) );
                 $log_bd -> setFecha( utf8_decode( $contenido[ 4 ] ) );
                 $log_bd -> setContenido( utf8_decode( $contenido[ 5 ] ) );
                 $log_bd -> setInfo_sesion( utf8_decode( $contenido[ 6 ] ) );

                 $log_bd -> guardar();
              }
         }  
         
       public function test()
         {
            
   
            echo "Clase: " . $this -> _class. "<br />";
            echo "Metodo: " . __METHOD__ . "<br />";
            echo "Linea: " . __LINE__ . "<br />";
            
            $this ->log( "Prueba DEBUG", Logger::$DEBUG, __METHOD__, __LINE__ );
            $this ->log( "Prueba INFO", Logger::$INFO );
            $this ->log( "Prueba WARN", Logger::$WARN );
            $this ->log( "Prueba ERROR", Logger::$ERROR );
            $this ->log( "Prueba FATAL", Logger::$FATAL);
            
            //$this -> guardarAcumulacionLogs();
         }  
   }
   
   
  /*$log = new Logger( "log.php", false, true, "d/M/y" ); 
  
  $log -> test();*/
   